#include "QCustomLibrary.h"
#include "PluginHelper.h"

static  StringMapHandle		g_stringMapHandle;
HANDLE  funCustomModuleInterface(const wchar_t* dllName)
{
	QString  strDllName = QString::fromWCharArray(dllName);
	if(g_stringMapHandle.contains(strDllName))
	{
		return g_stringMapHandle[strDllName];
	}
	return NULL;
}

QCustomLibrary::QCustomLibrary()
{

}

QCustomLibrary::~QCustomLibrary()
{

}

bool QCustomLibrary::unLoadPlugin( const wchar_t* filename )
{
	QString strLibFilName = QString::fromWCharArray(filename);
	QString strFullPath = PluginHelper::GetLocalAppDataPath() + strLibFilName;
	QString strFileName = PluginHelper::GetFileNameFromFilePath(strFullPath,false);
	QString strDllName  = PluginHelper::GetFileNameFromFilePath(strFullPath,true);
	char chFileName[MAX_PATH]={0};
	QCommonBase::StringToChar(strFileName,chFileName);
	bool  bRes = false;
	
	if(m_stringMapLib.contains(strDllName))
	{
		QLibrary* pLib = m_stringMapLib[strDllName];
		
		Q_ASSERT(pLib);
		if(!pLib->isLoaded())
		{
			//LogWriter::getLogCenter()->PrintLog(false,"%s no loading",chFileName);
			//Q_ASSERT(0);
		}
		else
		{
			bRes = pLib->unload();
			//LogWriter::getLogCenter()->PrintLog(bRes,"%s unload %s!",chFileName,bRes == true ? "success" : "error");
		}
		
		FREEMEMORY(pLib);
		m_stringMapLib.remove(strDllName);
	}

	return bRes;
}

bool QCustomLibrary::loadPlugin( const wchar_t* filename )
{
	QString strLibFilName = QString::fromWCharArray(filename);
	QString strFullPath = PluginHelper::GetLocalAppDataPath() + strLibFilName;
	QString strFileName = PluginHelper::GetFileNameFromFilePath(strFullPath);
	QString strDllName  = PluginHelper::GetFileNameFromFilePath(strFullPath,true);
	char chFileName[MAX_PATH]={0};
	QCommonBase::StringToChar(strFileName,chFileName);
	QLibrary* pLib = NULL;
	bool bRes=  false;
	if(m_stringMapLib.contains(strDllName))
	{
		pLib = m_stringMapLib[strDllName];
		Q_ASSERT(pLib);
		if(pLib->isLoaded())
		{	
			//LogWriter::getLogCenter()->PrintLog(true,"%s has already loaded!",chFileName);
			
		}
		else
		{
			pLib->setFileName(strFileName);
			bRes = pLib->load();
			if(!bRes)
			{
				char chError[MAX_PATH] = {0};
				QCommonBase::StringToChar(pLib->errorString(),chError);
				//LogWriter::getLogCenter()->PrintLog(LOG_ERROR,"%s load error:%s",chFileName,chError);
				FREEMEMORY(pLib);
				m_stringMapLib.remove(strDllName);
			}
			//LogWriter::getLogCenter()->PrintLog(bRes,"%s load %s!",chFileName,bRes == true ? "success" : "error");
			
		}
	}

	else
	{
		pLib = new QLibrary(strFullPath);
		bRes = pLib->load();
		if(!bRes)
		{
			char chError[MAX_PATH] = {0};
			QCommonBase::StringToChar(pLib->errorString(),chError);
			//LogWriter::getLogCenter()->PrintLog(LOG_ERROR,"%s load error:%s",chFileName,chError);
			FREEMEMORY(pLib);
		}
		else
			m_stringMapLib[strDllName] = pLib;
		

		//LogWriter::getLogCenter()->PrintLog(bRes,"%s load %s!",chFileName,bRes == true ? "success" : "error");
	}

	return bRes;
}

void* QCustomLibrary::getAppModule( const wchar_t* dllname )
{
	char chFileName[MAX_PATH]={0};
	PluginHelper::WCharToChar(dllname,chFileName);
	QString  strFileName = QString(chFileName);
	
	FUNC_GETREGISTERBANK fnBank = (FUNC_GETREGISTERBANK)getSymbolFun(strFileName,"GetAppModule");
	AppModule*  pModule = (AppModule*)(*fnBank)() ;
	if(pModule)
		pModule->InitModule(funCustomModuleInterface);
	return pModule;
}

HANDLE QCustomLibrary::getModuleInterface( const wchar_t* interfaceName )
{
	char chFileName[MAX_PATH]={0};
	PluginHelper::WCharToChar(interfaceName,chFileName);
	QString  strFileName = QString(chFileName);
	FUNC_GETREGISTERBANK fnBank= (FUNC_GETREGISTERBANK) getSymbolFun(strFileName,"GetAppModuleInterface");
	g_stringMapHandle[strFileName] = (*fnBank)() ;
	Q_ASSERT(fnBank != NULL);

	return fnBank ? (*fnBank)() : NULL;
}

void* QCustomLibrary::getSymbolFun( QString fileName,char* funName )
{
	char chFileName[MAX_PATH]={0};
	QCommonBase::StringToChar(fileName,chFileName);
	
	if(m_stringMapLib.contains(fileName))
	{
		QLibrary* pLib = m_stringMapLib[fileName];
		Q_ASSERT(pLib);
		if(pLib == NULL)  return NULL;

		if(pLib->isLoaded())
		{
			return pLib->resolve(funName);
		}
		else
		{
			//LogWriter::getLogCenter()->PrintLog(LOG_WARN,"%s no loading",chFileName);
		}
	}

	return NULL;
	
}

bool QCustomLibrary::initPluginModule( HANDLE pInstance )
{
	AppModule* pModule = (AppModule*) pInstance;
	Q_ASSERT(pModule);
	if(pModule)
		pModule->InitModule(funCustomModuleInterface);
	return true;
}
